package cn.cellcom.agent.online.client;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.cellcom.agent.common.AgentConstant;
import cn.cellcom.agent.common.AgentConstant.MEMBER_STATUS;
import cn.cellcom.agent.common.AgentConstant.RESULT;
import cn.cellcom.agent.j2ee.AgentListener;
import cn.cellcom.agent.online.handler.LogHandler;
import cn.cellcom.agent.online.message.ArchiveMessage;
import cn.cellcom.agent.online.message.BizMessage;
import cn.cellcom.agent.online.message.MessageConstant;
import cn.cellcom.agent.online.message.MessageConstant.ARCHIVE_EVENT;
import cn.cellcom.agent.online.message.MessageConstant.MULIT_TYPE;
import cn.cellcom.agent.online.wrapper.SessionWrapper;
import cn.cellcom.agent.pojo.TChannel;
import cn.cellcom.agent.pojo.TSession;
import cn.cellcom.agent.util.SerializableUtils;
import cn.cellcom.jar.util.DT;
import cn.cellcom.jar.util.LogUtil;
import cn.cellcom.jar.util.MyException;

/**
 * 
 * @author zhengyj
 * 
 */
public class SystemClient extends Client {
	private Logger log = LoggerFactory.getLogger(this.getClass());

	SessionWrapper session = null;

	public SystemClient(SessionWrapper session) {
		this.session = session;
	}

	/**
	 * 在线时通知昵称
	 * 
	 * @param receiver
	 * @param memberId
	 * @param memberType
	 * @param memberNickname
	 */
	public void sysSendMemberOnline(String receiver, String memberId, String memberType, String memberNickname) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("status", MEMBER_STATUS.ONLINE);
		map.put("member", memberId);
		map.put("memberType", memberType);
		map.put("memberNickname", memberNickname);
		log.info("[{}] receive the member[{}]'s status[{}]", receiver, memberId, MEMBER_STATUS.ONLINE);

		this.sysSendNotify(receiver, MessageConstant.MESSAGE_NOTIFY.MEMBER_STATUS, map);
	}

	/**
	 * 通知会话变更
	 * 
	 * @param sessionWrapper
	 *            相关会话
	 * @param client
	 *            变更的客户
	 * @param online
	 *            进入还是离开
	 */
	public void sysSendMemberStatus(String receiver, String memberId, String memberType, MEMBER_STATUS status) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("status", status);
		map.put("member", memberId);
		map.put("memberType", memberType);
		log.info("[{}] receive the member[{}] status[{}]", receiver, memberId, status);

		this.sysSendNotify(receiver, MessageConstant.MESSAGE_NOTIFY.MEMBER_STATUS, map);
	}

	/**
	 * 发送某种通知
	 * 
	 * @param crm
	 * @param session
	 * @return
	 */
	public RESULT sysSendNotify(String receiver, MessageConstant.MESSAGE_NOTIFY notify, Object objectOrText) {
		BizMessage m = new BizMessage();
		m.setReceiver(receiver);
		m.setPid(session.getPid());
		m.setSid(session.getId());
		m.setCid(session.getSession().getCrm());
		if (objectOrText instanceof String) {
			m.setText(String.valueOf(objectOrText));
		} else {
			m.setObject(objectOrText);
		}
		m.setEvent(MessageConstant.MESSAGE_EVENT.NOTIFY);
		m.setNotify(notify);
		return this.sendBizMessage(m);
	}

	/**
	 * 系统发出消息
	 * 
	 * @param text
	 */
	public void sysSendText(String text) {
		if (StringUtils.isBlank(text)) {// 一些配置信息是有可能为空的,不认为是错误
			return;
		}
		archive(session, ARCHIVE_EVENT.CHAT, text);
		session.message(this, text, null, MessageConstant.MULIT_TYPE.TEXT.name());
	}

	/**
	 * 静默提示
	 * 
	 * @param session
	 */
	public void silentNotice(SessionWrapper session) {
		TSession s = session.getSession();
		if (s.getStep().equals(AgentConstant.SESSION_STEP.AGENT.name())) {
			session.setSentSilentNotice(true);
			this.sysSendText(session.getSetting().getSilentNoticeTip());
		}
	}

	/**
	 * 静默结束会话
	 * 
	 * @param session
	 */
	public void silentEnd(SessionWrapper session) {
		TSession s = session.getSession();
		if (s.getStep().equals(AgentConstant.SESSION_STEP.AGENT.name())) {
			session.setSilentEnding(true);
			log.info("session [{}] is silent end.", s.getId());
			this.archive(session, ARCHIVE_EVENT.SILENT_END, null);
			// 下发对话通知
			this.sysSendText(session.getSetting().getSilentEndTip());
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
			}
			/*
			 * 结束会话[首先由坐席结束，如果坐席不在线则由访客自行结束，两者都不在线那就是异常了] AgentClient master =
			 * session.getMastAgent(); if (master != null) { log.info("session
			 * [{}] is silent end, and the master agent[{}] is online, so call
			 * the endSession.", s.getId(), master.getId());
			 * master.endSession(session.getId(),
			 * AgentConstant.AG_SESSION_END_TYPE.BY_SILENT); } else { }
			 */
			if (session.getVisitor() != null) {
				log.info("session [{}] is silent end, and the visitor online.", s.getId());
				session.getVisitor().endSession(session.getId(), AgentConstant.SESSION_END_TYPE.BY_SILENT);
			} else {
				log.info("session [{}] is silent end, but the visitor offline, so update db.", s.getId());
				TSession tsession = session.getSession();
				tsession.setEndTime(System.currentTimeMillis());
				tsession.setEndType(AgentConstant.SESSION_END_TYPE.BY_SILENT.name());
				this.updateSessionDb(tsession);
				//通知坐席
				session.notifyToAgentForSilentEnd();
			}
		}
	}

	private void updateSessionDb(TSession session) {
		try {
			AgentListener.getStaticDao().myUpdate(session);
		} catch (MyException e) {
			LogUtil.e(this.getClass(), "[" + session.getId() + "]update tsession error", e);
		}
	}

	public void archive(SessionWrapper session, ARCHIVE_EVENT event, String text) {
		this.archiveWithId(session, IDManager.getMid(), event.toString(), text, MULIT_TYPE.TEXT.name(), null);
	}

	public void archiveWithId(SessionWrapper session, String mid, String event, String text, String mtype, Object obj) {
		TSession tsession = session.getSession();
		ArchiveMessage am = new ArchiveMessage();
		try {
			am.setEvent(event);
			am.setId(mid);
			if (obj != null) {
				am.setObject(new String(SerializableUtils.serialize(obj)));
			}
			am.setOrg(tsession.getOrg());
			am.setPid(tsession.getPid());
			am.setSender(this.getId());
			am.setSenderNickname(this.getNickname());
			am.setSenderRole(AgentConstant.USER_TYPE_SYSTEM);
			am.setShowPolicy(MessageConstant.ARCHIVE_SHOW_POLICY.ALL.name());
			am.setText(text);
			am.setSid(tsession.getId());
			am.setCid(tsession.getCrm());
			am.setTime(DT.getNow2());
			am.setMultiType(mtype);
			LogHandler.archive(am);
		} catch (Exception e) {
			log.error("Archive visitor message fail:" + am, e);
		}
	}

	@Override
	public String getHttpSessionId() {
		return MessageConstant.SYSTEM;
	}

	@Override
	public String getId() {
		return MessageConstant.SYSTEM;
	}

	@Override
	public Map<String, String> getIdMap() {
		return new HashMap<String, String>();
	}

	@Override
	public String getOrg() {
		return session.getSession().getOrg();
	}

	@Override
	public String getNickname() {
		return session.getSetting().getOrgName();// "系统";
	}

	@Override
	public String getSender(TChannel tChannel) {
		return MessageConstant.SYSTEM;
	}

}
